package com.xbongbong.paas.help.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkConditionPoJo;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.help.analysis.data.FormDataLinkSearchAnalysisDataHelp;
import com.xbongbong.paas.help.service.FormDataLinkSearchService;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.LinkConditionDataDTO;
import com.xbongbong.paas.pojo.dto.LinkSearchGetDTO;
import com.xbongbong.paas.pojo.dto.LinkSearchListDTO;
import com.xbongbong.paas.pojo.dto.ParseSingleRowDataDTO;
import com.xbongbong.paas.pojo.vo.LinkSearchGetVO;
import com.xbongbong.paas.pojo.vo.LinkSearchListVO;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.service.LinkDataService;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.vo.FormDataVO;
import com.xbongbong.saas.constant.StringConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author: wufeng
 * @date: 2018/11/14 15:57
 * @desrcption:
 */
@Component
public class FormDataLinkSearchUpdateGetServiceImpl implements FormDataLinkSearchService {

    private static  final Logger LOG = LoggerFactory.getLogger(FormDataLinkSearchUpdateGetServiceImpl.class);

    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private FormDataLinkSearchAnalysisDataHelp formDataLinkSearchAnalysisDataHelp;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private LinkDataService linkDataService;

    @Override
    public LinkSearchGetVO formDataLinkDataGet(LinkSearchGetDTO linkSearchGetDTO) throws XbbException{
        LinkSearchGetVO linkSearchGetVO = new LinkSearchGetVO();
        try {
            JSONObject jsonObject = linkSearchGetDTO.getJsonObject();
            if(linkSearchGetDTO.getFormExplainMap().isEmpty()){
                Map<String, Object> explainParam = BeanUtil.convertBean2Map(linkSearchGetDTO, true);
                explainParam.remove("menuId");
                explainParam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.list(explainParam);
                if(formExplainList == null){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                Map<String, PaasFormExplainEntity> formExplainMap = new HashMap<>(formExplainList.size());
                formExplainList.forEach((item)->{
                    formExplainMap.put(item.getFormId().toString(), item);
                });
                linkSearchGetDTO.setFormExplainMap(formExplainMap);
            }
            Map<String, FieldAttrEntity> explainMap = linkSearchGetDTO.getExplainMap();
            Iterator iterator = explainMap.keySet().iterator();
            while(iterator.hasNext()){
                String attr = iterator.next().toString();
                FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                linkSearchGetDTO.setAttr(attr);
                if(FieldTypeEnum.LINK_QUERY.getType().equals(fieldAttrEntity.getFieldType())){
                    // 检索表单的关联查询
                    linkSearchGetDTO.setSubAttr("");
                    getLinkSearchData(linkSearchGetDTO, fieldAttrEntity, jsonObject);
                }else if(FieldTypeEnum.SUB_FORM.getType().equals(fieldAttrEntity.getFieldType())){
                    List<? extends FieldAttrEntity> explainList = fieldAttrEntity.getSubForm().getItems();
                    for(FieldAttrEntity subFieldAttr: explainList){
                        // 遍历子表单的关联查询
                        if(FieldTypeEnum.LINK_QUERY.getType().equals(subFieldAttr.getFieldType())){
                            JSONArray jsonArray = jsonObject.getJSONArray(attr);
                            JSONArray result = new JSONArray();
                            if(Objects.isNull(jsonArray)){
                                JSONObject subJsonObject = new JSONObject();
                                String subKey = subFieldAttr.getAttr();
                                linkSearchGetDTO.setSubAttr(subKey);
                                getLinkSearchData(linkSearchGetDTO, subFieldAttr, subJsonObject);
                                result.add(subJsonObject);
                            }else{
                                for(int i=0; i<jsonArray.size(); i++){
                                    JSONObject subJsonObject = jsonArray.getJSONObject(i);
                                    String subKey = subFieldAttr.getAttr();
                                    linkSearchGetDTO.setSubAttr(subKey);
                                    getLinkSearchData(linkSearchGetDTO, subFieldAttr, subJsonObject);
                                    result.add(subJsonObject);
                                }
                            }
                            jsonObject.put(attr, result);
                        }
                    }
                }
            }
            linkSearchGetVO.setResult(jsonObject);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("获取关联数据失败，", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return linkSearchGetVO;
    }

    /**
     * 获取关联查询数据
     * @param linkSearchGetDTO
     * @param fieldAttrEntity 字段对象
     * @param jsonObject 数据（可能是子表单数据）
     * @throws XbbException
     */
    public void getLinkSearchData(LinkSearchGetDTO linkSearchGetDTO, FieldAttrEntity fieldAttrEntity, JSONObject jsonObject) throws XbbException{
        try {
            LinkSearchListDTO linkSearchListDTO = new LinkSearchListDTO();
            BeanUtil.copyProperties(linkSearchGetDTO, linkSearchListDTO);
            String attr = linkSearchGetDTO.getAttr();
            String subAttr = linkSearchGetDTO.getSubAttr();
            JSONObject data = linkSearchGetDTO.getJsonObject();
            if (fieldAttrEntity != null) {
                LinkInfoPojo linkInfoPojo = fieldAttrEntity.getLinkInfo();
                if(Objects.nonNull(linkInfoPojo)){
                    List<LinkConditionPoJo> condition = linkInfoPojo.getCondition();
                    List<LinkConditionDataDTO> valueList = new ArrayList<>();
                    condition.forEach((conditionItem) -> {
                        Object value = data.get(conditionItem.getAttr());
                        if (value != null) {
                            LinkConditionDataDTO linkConditionDataDTO = new LinkConditionDataDTO();
                            linkConditionDataDTO.setAttr(conditionItem.getAttr());
                            linkConditionDataDTO.setValue(value);
                            valueList.add(linkConditionDataDTO);
                        }
                    });
                    Long formId = linkInfoPojo.getLinkFormId();
                    if(Objects.isNull(formId)){
                        if(StringUtil.isNotEmpty(subAttr)){
                            jsonObject.put(subAttr, "");
                        }else{
                            jsonObject.put(attr, "");
                        }
                        return;
                    }
                    PaasFormExplainEntity paasFormExplainEntity = linkSearchGetDTO.getFormExplainMap().get(formId.toString());
                    if(Objects.isNull(paasFormExplainEntity)){
                        if(StringUtil.isNotEmpty(subAttr)){
                            jsonObject.put(subAttr, "");
                        }else{
                            jsonObject.put(attr, "");
                        }
                        return;
                    }
                    linkSearchListDTO.setAttr(attr);
                    linkSearchListDTO.setSubAttr(subAttr);
                    linkSearchListDTO.setValue(valueList);
                    linkSearchListDTO.setFieldList(linkInfoPojo.getLinkedAttr());
                    linkSearchListDTO.setFormId(formId);
                    linkSearchListDTO.setLinkInfo(linkInfoPojo);
                    LinkSearchListVO linkSearchListVO = linkDataService.filterLinkSearch(linkSearchListDTO);
                    if(StringUtil.isNotEmpty(subAttr)){
                        jsonObject.put(subAttr, "");
                    }else{
                        jsonObject.put(attr, "");
                    }
                    if (linkSearchListVO != null && !linkSearchListVO.getPaasFormDataESList().isEmpty()) {
                        FormDataVO paasFormDataEsEntity = linkSearchListVO.getPaasFormDataESList().get(0);
                        ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
                        BeanUtil.copyProperties(linkSearchGetDTO, parseSingleRowDataDTO);
                        parseSingleRowDataDTO.setDataJsonObject(paasFormDataEsEntity.getData());
                        parseSingleRowDataDTO.setExplainMap(ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null));
                        ParseSingleRowDataVO parseSingleRowDataVO = formDataLinkSearchAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
                        if(Objects.nonNull(parseSingleRowDataVO)){
                            if(StringUtil.isNotEmpty(subAttr)){
                                jsonObject.put(subAttr, parseSingleRowDataVO.getResult());
                            }else {
                                jsonObject.put(attr, parseSingleRowDataVO.getResult());
                            }
                        }
                    }
                }
            }
        }catch (XbbException e){
            LOG.error("获取关联数据失败，", e);
            throw e;
        }catch (Exception e) {
            LOG.error("获取关联数据失败，", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }
}
